﻿using System;
using System.Collections.Generic;

using System.Text;

namespace QQZiFramework
{
    public class ITreeDBEntity : IDBEntity
    {
        public ITreeDBEntity()
        {
            children = new TreeDBEntityCollection(this);
        }
        
        TreeDBEntityCollection children;
        public TreeDBEntityCollection Children
        {
            get { return children; }
            set { children = value; }
        }

        protected ITreeDBEntity _Parent { get; set; }

        [Newtonsoft.Json.JsonIgnore]
        [DBField(Usage = DBFieldUsage.NoField)]
        public ITreeDBEntity Parent
        {
            get { return _Parent; }
            // set
            // {
            //     if(_Parent == value) return;
            //     _Parent = value;
            //     if (value != null) value.Children.Add(this);
            // }
        }

        /// <summary>
        /// 递归查找
        /// </summary>
        /// <param name="match"></param>
        /// <returns></returns>
        public ITreeDBEntity Find(Predicate<ITreeDBEntity> match)
        {
            if (this.Children != null)
            {
                ITreeDBEntity entity = this.Children.Find(match);
                if (entity != null) return entity;
                foreach (ITreeDBEntity sub in this.Children)
                {
                    entity = sub.Find(match);
                    if (entity != null) return entity;
                }
            }
            return null;
        }

        /// <summary>
        /// 移除树中的元素
        /// </summary>
        /// <param name="primaryVal"></param>
        public void Remove(object primaryVal)
        {
            ITreeDBEntity findEntity = Find(X => X.GetPrimaryValue().Equals(primaryVal));
            if (findEntity != null)
            {
                if (findEntity.Children.Count > 0) throw new ClientException("有下级代理商，不允许删除！");
                if (findEntity.Parent != null) { findEntity.Parent.Children.Remove(findEntity); }
            }
        }


        public class TreeDBEntityCollection : IList<ITreeDBEntity>
        {
            ITreeDBEntity parentDBEntity { get; set; }

            public TreeDBEntityCollection(ITreeDBEntity parent)
            {
                parentDBEntity = parent;
                lst = new List<ITreeDBEntity>();
            }
            private List<ITreeDBEntity> lst;

            public ITreeDBEntity Find(Predicate<ITreeDBEntity> match)
            {
                return lst.Find(match);
            }

            public int IndexOf(ITreeDBEntity item)
            {
                return lst.IndexOf(item);
            }

            public void Insert(int index, ITreeDBEntity item)
            {
                lst.Insert(index, item);
            }

            public void RemoveAt(int index)
            {
                lst.RemoveAt(index);
            }

            public ITreeDBEntity this[int index]
            {
                get
                {
                    return lst[index];
                }
                set
                {
                    lst[index] = value;
                }
            }

            public void Add(ITreeDBEntity item)
            {
                lst.Add(item);
                item._Parent = parentDBEntity;

            }

            public void AddRange(IEnumerable<ITreeDBEntity> collection)
            {
                lst.AddRange(collection);
            }

            public void Clear()
            {
                lst.Clear();
            }

            public bool Contains(ITreeDBEntity item)
            {
                return lst.Contains(item);
            }

            public void CopyTo(ITreeDBEntity[] array, int arrayIndex)
            {
                lst.CopyTo(array, arrayIndex);
            }

            public int Count
            {
                get { return lst.Count; }
            }

            public bool IsReadOnly
            {
                get { return false; }
            }

            public bool Remove(ITreeDBEntity item)
            {
                return lst.Remove(item);
            }

            public IEnumerator<ITreeDBEntity> GetEnumerator()
            {
                return lst.GetEnumerator();
            }

            System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
            {
                return lst.GetEnumerator();
            }

            public List<ITreeDBEntity> ToList()
            {
                return lst;
            }
        }
    }


    public class TreeReationExtend
    {
        public int NodeId { get; set; }
        public int Deep { get; set; }

        public int SubNodeId { get; set; }
    }
}
